package com.chenfan.filestore.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.chenfan.infra.context.TenantContextHolder;
import com.chenfan.infra.context.UserContextHolder;
import com.chenfan.infra.vo.BaseUserVO;
import com.chenfan.infra.vo.UserVO;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author senry
 */
@Configuration
@MapperScan(value = "com.chenfan.**.repository.**", sqlSessionFactoryRef = "sqlSessionFactory")
public class DataSourcesConfig {

    @Bean(name = "batch")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource batch() {
        return new DruidDataSource();
    }

    @Bean
    @Primary
    public DynamicDataSource dataSource(@Qualifier("batch") DataSource batch) {
        Map<Object, Object> targetDataSources = new HashMap<>(16);
        targetDataSources.put(DS.MAIN, batch);
        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSources);
        dataSource.setDefaultTargetDataSource(batch);
        return dataSource;
    }

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    @Bean
    public MybatisSqlSessionFactoryBean sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean fb = new MybatisSqlSessionFactoryBean();
        fb.setDataSource(dataSource(batch()));
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
            @Override
            public Expression getTenantId() {
                UserVO userVO = UserContextHolder.getUserVo();
                Long tenantId = Optional.ofNullable(userVO).map(BaseUserVO::getTenantId).orElse(TenantContextHolder.getTenantId());
                return tenantId == null ? null : Optional.of(new LongValue(tenantId)).orElse(null);
            }

            @Override
            public boolean ignoreTable(String tableName) {
//                return IGNORE_FLAG.get()||tables.contains(tableName);
                return false;
            }
        }));
        fb.setPlugins(interceptor, paginationInterceptor());
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setCallSettersOnNulls(true);
        fb.setConfiguration(configuration);
//        fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return fb;
    }

}


